目標項目:
要達成下方的自訂導覽列效果,首先加入所需的三個圖示
在 drawable 資料夾右鍵 New -> Vector Asset

接著在 res 資料夾底下新增 menu 資料夾,並加入 bottom_navigation.xml 檔案,裡面就是下方導覽列的介面設置

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/title_home" />
    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:title="@string/title_dashboard" />
    <item
        android:id="@+id/navigation_notifications"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="@string/title_notifications" />
</menu>
建立好後,我們還需要寫一個自訂 class 繼承 NavigationView
package com.example.river.bottomnavigation
import android.content.Context
import android.support.design.widget.NavigationView
class BottomNavigationView(context: Context?) : NavigationView(context)
再來就可以到我們首頁介面的 activity_main 檔中,加入剛建立好的 layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_navigation" />
</android.support.constraint.ConstraintLayout>
三個圖示按下時會對應三個 Fragment
class HomeFragment : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_home, container, false)
    }
    override fun onStart() {
        homeButton.setOnClickListener {
            val intent = Intent(activity,Home2Activity::class.java)
            startActivity(intent)
        }
        super.onStart()
    }
}
class DashboardFragment : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_dashboard, container, false)
    }
}
class NotificationFragment  : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_notifications, container, false)
    }
}
首先是首頁的 MainActivity
建立一個列舉類別,然後建立一個 type 變數來代表現在按下的 item
另外需要一個 supportFragmentManager 來管理 fragment
後續也會使用 FragmentTransaction() 來執行 fragment 間的切換
class MainActivity : AppCompatActivity() {
    enum class FragmentType {
        Home,
        Notifications,
        Dashboard
    }
    var type = FragmentType.Home
    val manager = this.supportFragmentManager
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        navigation.setOnNavigationItemSelectedListener {
            when (it.itemId) {
                R.id.navigation_home -> {
                    type = FragmentType.Home
                }
                R.id.navigation_notifications -> {
                    type = FragmentType.Notifications
                }
                R.id.navigation_dashboard -> {
                    type = FragmentType.Dashboard
                }
                else -> {
                    return@setOnNavigationItemSelectedListener false
                }
            }
            changeScenario()
            true
        }
        changeScenario()
    }
    fun changeScenario() {
        val transaction = manager.beginTransaction()
        when (type) {
            FragmentType.Home -> {
                val homeFragment = HomeFragment()
                transaction.replace(R.id.container, homeFragment)
            }
            FragmentType.Dashboard -> {
                val dashboardFragment = DashboardFragment()
                transaction.replace(R.id.container, dashboardFragment)
            }
            FragmentType.Notifications -> {
                val notificationFragment = NotificationFragment()
                transaction.replace(R.id.container, notificationFragment)
            }
        }
        transaction.addToBackStack(null)
        transaction.commit()
    }
}
先自訂一個 Home2Activity 類別
使用 setDisplayHomeAsUpEnabled(true) 來顯示左上角的返回按鈕
並覆寫 onOptionsItemSelected 方法來觸發 onBackPressed 回上一頁
class Home2Activity: AppCompatActivity()  {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.home2)
        this.title = "Home 2"
        this.supportActionBar?.setDisplayHomeAsUpEnabled(true)
        home2Button.setOnClickListener {
            val intent = Intent(this,Home3Activity::class.java)
            startActivity(intent)
        }
    }
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home -> {
                onBackPressed()
                return true
            }
        }
        return super.onOptionsItemSelected(item)
    }
}
接著是第三個 Activity,按鈕設定回到 MainActivity
class Home3Activity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.home3)
        this.title = "Home 3"
        this.supportActionBar?.setDisplayHomeAsUpEnabled(true)
        home3Button.setOnClickListener {
            val intent = Intent(this, MainActivity::class.java)
            startActivity(intent)
        }
    }
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home -> {
                onBackPressed()
                return true
            }
        }
        return super.onOptionsItemSelected(item)
    }
}